const https = require('https');
const urlQuery = require("querystring");
const redis = require("../../redis/redis-client");
const axios = require("axios");
const puppeteer = require("puppeteer");

// 引入 nodemailer 模块
const nodemailer = require("nodemailer");

let timer = null

// 创建一个 SMTP 传输对象
const transporter = nodemailer.createTransport({
  service: "qq", // 邮箱服务名
  auth: {
    user: "k9918@qq.com", // 邮箱账号
    pass: "ggyyazcosqolcbdh" // 邮箱授权码
  }
});
// 设置邮件选项
const mailOptions = {
  from: "k9918@qq.com", // 发件人邮箱
  to: "85423072@qq.com", // 收件人邮箱，可以是多个，用逗号分隔
  subject: "error", // 邮件主题
  text: "This is a test email from NodeMailer." // 邮件正文，纯文本格式
};


(async function updateFn() {

  // 连接已打开的浏览器
  let wsKey = await axios.get('http://localhost:21222/json/version');
  const browser = await puppeteer.connect({
    browserWSEndpoint: wsKey.data.webSocketDebuggerUrl,
    defaultViewport: null,
    slowMo: 100,
    headless: true,
    timeout: 60000 * 5
  })

  //使用 puppeteer.launch 启动 Chrome
  // 打开新的浏览器
  // const browser = await puppeteer.launch(
  //   {
  //     headless: false,
  //     defaultViewport: null,
  //     slowMo: 100,
  //     args: [
  //       '--no-sandbox',
  //       '--disable-features=site-per-process',
  //       '--start-maximized'
  //     ],
  //     timeout: 60000
  //   },
  // );

  // 当前在第几页
  let currentPage = 1;

  // 出库工作台的数据列表
  let outWorkbenchList = [];

  // 新增的采购合同信息item
  let addList = [];

  // 被修改过的商品信息的合同id
  let changeGoods = [];

  //当前执行的条数
  let currentItem = 0;

  //每条占滚动条比率
  let ScrollRatio = 0;

  // 总分页数
  let totalpages = 0;

  // 总条数
  let totalItem = 0;

  // 每次移动条数
  const count = 15;


  const page = await browser.newPage();
  await page.goto("http://10.139.3.16/sainty/");

  page.setDefaultNavigationTimeout(60000 * 5); // 1 hour


  // 监听error
  process.on('unhandledRejection', async (reason, p) => {
    console.error('Unhandled Rejection at: Promise:zk', 'reason:', reason);
    // changeGoods = [];
    // 开启新一轮轮循
    if (timer) {
      clearTimeout(timer)
    }

    timer = setTimeout(async () => {
      timer = null;
      let cp = currentPage - 1
      updateFn(cp * count, cp)
      await page.close();
      //  sendM(reason + "当前item" + cp * count + "当前页数" + cp)
    }, 5000);
  });


  const submitBtnEle = await page.$("input[id='LOGINSUBMIT']");
  if (submitBtnEle) {
    await submitBtnEle.click();
  }

  await page.waitForSelector(".menu-warp");
  const lineMenu = await page.$("a[title='仓储物流']");
  await lineMenu.click();

  const inputWorkbench = await page.$("a[title='出库工作台']");
  await inputWorkbench.click();

  const iframe = await page.waitForFrame((frame) => (frame.url().includes("27.25.20.10.10.N9STJ.html")));

  if (iframe) {

    // 监听请求的响应的
    onPageList();

    // 输入入库运编号
    const inputIdEl = await iframe.$("input[name='salshipcode']");
    await inputIdEl.type("G118", { delay: 20 });

    // // 点击展开
    // const developEl = await iframe.$("#UIA_purworkspaceQ__switchcss_ui-pane-collapsed");
    // await developEl.click();

    // // 取消勾选只查待入库>0
    // const checkboxEl = await iframe.$("input[name='coropt#20']");
    // await checkboxEl.click();

    // // 签约日期取消
    // const dateEl = await iframe.$("input[name='odate.[from]']");
    // await dateEl.click();
    // await page.keyboard.press('Backspace');

    // const dateEl = await iframe.$("#UIA_purworkspaceQ_odateform .ui-input-combobtn");
    // await dateEl.click();

    // const NAVYEARNEXT = await iframe.$("#NAVYEARNEXT");
    // await NAVYEARNEXT.click();

    // const NAVMONPREV = await iframe.$("#NAVMONPREV");

    // for (let i = 0; i < 6; i++) {
    //   await NAVMONPREV.click();
    // }
    // const day = await iframe.$("#DAYSELECT .bodyrow .day");
    // await day.click();

    // 点击查询
    const searchEl = await iframe.$("#UIA_queryQ_btn_wrefreshtbls");
    await searchEl.click();

    await page.waitForTimeout(3000);

  }

  // 方法区--------------------------------------------------------------


  //轮循获取入库工作台列表
  async function forList() {
    await page.waitForTimeout(2000);

    //计算比率
    var scrollHeight = await iframe.$eval(".ui-gridtable .ui-grid-bar", el => el.scrollHeight)

    ScrollRatio = scrollHeight / totalItem;

    // 移除监听采购订单合同列表
    page.removeListener('response');

    onGoods();

    // redis.getString("outCurrentPage").then(res => {
    //   if (res) {
    //     currentPage = res;
    //     iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
    //       (el.scrollTop = ScrollRatio * currentPage * count),
    //       { ScrollRatio, currentPage, count }
    //     )
    //   }
    // })

    // -----------------------开始轮循点击采购合同---------------------------------
    await forClickId();
  }

  // 循环点击采购订单合同 结束后重新轮循获取入库工作台列表
  async function forClickId() {

    // 当前页面的10条出库运编号
    let div = await iframe.$$eval(".gtable tbody tr:not(.emptyrow) td:nth-child(3)", node => node.map((el) => el.innerText.trim()));
    console.log("div:", div);

    // 当前页面10条需要点击的元素
    let divId = await iframe.$$(".gtable tbody tr:not(.emptyrow) td:nth-child(3)");

    // 截取页面显示的count条记录
    // 截取页面显示的count条记录
    if (currentPage < totalpages) {
      divId = divId.slice(0, count)
    }

    for (let i = 0; i < divId.length; i++) {
      console.log("当前索引：", i, "当前合同id", div[i]);
      let item = outWorkbenchList.find(({ deliveryTransportId }) => div[i] == deliveryTransportId);
      // console.log(item);
      if (item && item.goods.length == 0) {
        await divId[i].click({ clickCount: 2, delay: 100 });
        // 隐藏弹窗 影响点击事件
        const tiptext = await iframe.$(".x-tiptext.ui-layer-frame");
        if (tiptext) await iframe.$eval(".x-tiptext.ui-layer-frame", node => node.style.display = "none");
        //  找到出口脱单frame
        const goodsIframe = await page.waitForFrame((frame) => (frame.url().includes("27.15.40.G0.20.N9STJ.html")));
        // 点击发货商品
        const sendGoods = await goodsIframe.$("#TabOfUI_salordergrecord_tab");
        await sendGoods.click()
        await page.waitForTimeout(5000);

        const close = await page.$("#tabChangeUl li:last-child .icol-del3");
        await close.click()
      }
      // 记录执行过的条数
      currentItem++;
      console.log("当前执行的条数", currentItem, "总条数：", totalItem, "当前滚动次数：", currentPage, "滚动总次数:", totalpages);
    }
    if (currentPage > totalpages) {
      console.log("end---------outWorkbenchList:");

      // 更新未同步的商品
      // changeGoods.map((id) => {
      //   const index = outWorkbenchList.findIndex(({ contractId }) => id == contractId);
      //   if (index > -1) {
      //     sendUpdateGoodsToServer({ goods: outWorkbenchList[index].goods })
      //   }
      // })

      // redis.removeString("outCurrentPage")

      // 开启新一轮轮循
      page.close();
      setTimeout(() => {
        updateFn()
      }, 5000);
      return
    }

    if (currentPage <= totalpages) {
      // 执行完当前count条数 滚动翻页 继续执行
      iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
        (el.scrollTop = ScrollRatio * currentPage * count),
        { ScrollRatio, currentPage, count }
      )

      currentPage++;
      await forClickId()
    }

  }

  // 监听采购合同点击
  function onGoods() {
    page.on("response", (response) => {
      if (response.status() == 200) {
        if (response.url().includes("27.15.40.G0.20.N9STJ.do.ui")) {

          // url query 参数转json
          const queryJson = urlQuery.parse(response.request().postData());

          // 商品信息的接口
          if (queryJson && queryJson.gcodeCuicode) {
            response.text().then(res => {
              // 解析字符串形的对象
              const resData = eval("(" + res + ")");
              // 存储的字段数组
              const fields = resData.fields;

              let goods = [];

              resData.rows.map((item) => {
                goods.push({
                  "clientOrderId": item[1],//客户订单号
                  "clientItemId": item[2], //客户货号
                  "hsCode": item[3], //海关编码
                  "auxiliaryCode": item[4],//辅码
                  "goodsName": item[7],//商品名称
                  "englishName": item[8],//英文名称
                  "actualSendCount": item[13],//实际出运数量
                  "actualSendUnits": item[14],//实际出运单位
                  "totalPackages": item[20], //包装件数 总件数
                  "packagesUnit": getValueByNameId("qtxunit", item[21], fields), //包装单位
                  "clearanceCount": item[22],//报关数量
                  "clearanceUnits": item[23],//报关单位
                  "roughWeight": item[26], //毛重
                  "netWeight": item[27], //净重
                  "roughWeightTotal": item[28], //毛重合计
                  "netWeightTotal": item[29], //净重合计
                  "volumeLength": item[30],//尺寸描述长度
                  "volumeWidth": item[31],//尺寸描述宽度
                  "volumeHeight": item[32],//尺寸描述高度
                  "volumeTotal": item[33],//体积合计
                  "clearanceGoodsName": item[34],//开票及报关品名
                  "builtinNum": item[35], //内装数量
                  "exteriorNum": item[36], //外装数量
                  "packType": getValueByNameId("packtype", item[47], fields), //包装类型
                  "purchaseContractId": item[51],//采购合同号
                  "exportContractId": item[52],//出口合同号
                  "specification": item[53],//规格
                  "boxId": item[81],//箱号
                  "matrixingRatio": item[82], //换算比例
                  "total": item[83], //统计总数
                  "units": getValueByNameId("qtcunit", item[84], fields), //统计单位
                  "domesticSource": getValueByNameId("domesticsource", item[88], fields),//境内货源地
                  "remarks": item[115],//备注
                  "deliveryTransportId": item[100].trim()
                });
              });

              //  把goods放入采购合同id的goods里
              if (goods.length) {
                const deliveryTransportIds = outWorkbenchList.find(({ deliveryTransportId }) => deliveryTransportId == goods[0].deliveryTransportId);
                if (deliveryTransportIds) {
                  deliveryTransportIds.goods = goods
                }

                // 要更新的商品信息
                console.log("要更新的当前商品信息的合同列表changeGoods:", changeGoods);

                const index = changeGoods.findIndex((id) => goods[0].contractId == id);

                if (index > -1) {
                  const deliveryTransportIds = outWorkbenchList.filter(({ deliveryTransportId }) => deliveryTransportId == changeGoods[index]);
                  deliveryTransportIds.map((item) => {
                    // 发送更新的数据
                    sendUpdateListToServer(item);
                  })

                  console.log("2发送更新的goods:", "{ goods: goods }并删除", changeGoods[index]);
                  changeGoods.splice(index, 1);
                }
              }
            })
          }

          // 商品详情的接口 获取出库运编号id 和修改日期
          if (queryJson && queryJson["__Json_._LoadWFInfo"]) {
            response.text().then(res => {

              // 解析字符串形的对象
              const resData = eval("(" + res + ")");

              // 遍历新增的出库列表 
              if (resData.rows.length) {
                addList.map((item) => {
                  if (item.deliveryTransportId == resData.rows[0][0].trim()) {
                    // 发送后 同步到本地
                    sendUpdateListToServer(item).then(() => {
                      // key 出口合同号+ 出库运编号id+客户货号+超出天数+发货数量   value 1
                      const listItemKey = item.exportContractId + item.deliveryTransportId + item.clientItemId + item.daysOut + item.total;
                      // 本地存储
                      redis.setString(listItemKey, 1)
                    });
                  }
                });

                // 服务端记录的修改时间
                const changeTime = new Date(resData.rows[0][12]).getTime();

                const key = resData.rows[0][0].trim() + "time"

                // key 出口合同号+ 出库运编号id+客户货号+超出天数+发货数量   value 1
                // const key = (item.exportContractId + item.deliveryTransportId + item.clientItemId + item.daysOut + item.total)
                // // console.log(key);
                // // redis.setString(key, 1);
                // if (item.goods.length) {
                //   console.log("1发送更新的goods:", "{ goods: goods }");
                // }

                // key 出库运编号id  value 修改时间


                redis.getString(key).then(res => {

                  if (!res) {
                    // 本地没有代表新增的数据 需要保存到本地
                    redis.setString(key, changeTime);

                    console.log("changeGoods push的合同id:", resData.rows[0][0].trim());
                    changeGoods.push(resData.rows[0][0].trim())

                  } else if (changeTime > res) {
                    // 
                    console.log("被修改的出库运编号:", resData.rows[0][0].trim());
                    changeGoods.push(resData.rows[0][0].trim())
                    redis.setString(key, changeTime);

                    console.log("修改时间:", changeTime, "当前保存的时间:", res, "是否修改过", changeTime > res);
                  }
                });
              }
            })
          }
        }
      }
    })
  }

  // 监听页面请求
  function onPageList() {
    page.on("response", (response) => {
      if (response.status() == 200) {
        if (response.url().includes("27.25.20.10.10.N9STJ.do.ui")) {

          // url query 参数转json
          const queryJson = urlQuery.parse(response.request().postData());

          // 当前组织代码 G118
          if (queryJson && queryJson.salshipcode && queryJson.salshipcode == "G118") {
            response.text().then(res => {
              // 解析字符串形的对象
              const resData = eval("(" + res + ")");
              // 存储的字段数组
              const fields = resData.fields;

              // 总数据条数
              totalItem = resData.rows.length;

              // 计算需要拖动滚动条几次
              totalpages = Math.floor(totalItem / count);

              resData.rows.map((item) => {

                let contractItem = {
                  "exportContractId": item[0], //出口合同号
                  "deliveryTransportId": item[2].trim(), //出库运编号
                  "clientName": getValueByNameId("ccode", item[5], fields), //客户
                  "clientItemId": item[6], //客户货号
                  "deliveryDate": item[7], //出运确认日期
                  "transportId": item[8], //入库运编号
                  "warehouse": getValueByNameId("scode", item[9], fields),//发货仓库
                  "daysOut": item[10],//超出天数
                  "goodsName": item[11],//商品名称
                  "total": item[15],//发货数量
                  "sentNumber": item[16],//已出库数量
                  "willSendNumber": item[17],//待出库数量
                  "units": getValueByNameId("qtcunit", item[18], fields),//单位
                  "member": getValueByNameId("wcode", item[30], fields),//人员
                  "department": getValueByNameId("bcode", item[31], fields),//部门
                  "operator": getValueByNameId("corpbcode", item[32], fields),//经营单位
                  "goods": []//货品
                }

                outWorkbenchList.push(contractItem)

                // key 出口合同号+ 出库运编号id+客户货号+超出天数+发货数量   value 1
                const key = (item[0] + item[2].trim() + item[6] + item[10] + item[15]);
                // console.log(key);

                redis.getString(key).then(res => {
                  if (!res) {
                    // 本地没有 需要更新
                    console.log("需要更新的contractItem");
                    addList.push(contractItem)
                  }
                });
              })

              // 循环获取列表
              forList()
            })
          }
        }
      }
    })
  }

  /**
  * 
  * @param {*} name 字段标识
  * @param {*} Id 字段的id值
  * @param {*} array 所有的字段信息数组
  * @returns 匹配到的值
  */
  function getValueByNameId(name, Id, array) {
    let value = "";
    array.map((item) => {
      if (item.name == name) {
        value = item.valueMap[Id]
      }
    })
    return value
  }

  // 更新出库列表接口
  function sendUpdateListToServer(data) {
    return new Promise((resole) => {
      const postData = JSON.stringify(data);
      // console.log(postData);
      const req = https.request({
        hostname: 'zhuyiyun.com',
        path: '/openapi/webhook/842298925882507267/846312949730738179',
        port: 443,
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'secretKey': '8b95cf4b511b49b2901272c4a1351b57'
        }
      }, (res) => {
        resole("ok")
        console.log("statusCode:", res.statusCode);
      });

      // 设置要发送的内容
      req.write(postData);
      // 如果出错就在控制台输出错误信息
      req.on('error', err => {
        console.log(err);
      });

      req.end();

    })
  }

})();